package webdav

import (
	"context"
	"errors"
	"fmt"
	"golang.org/x/net/webdav"
	"log"
	"my189go/pkg"
	"net/http"
	"os"
	"strings"
)

var errUnsupportedMethod = errors.New("webdav: unsupported method")

type CloudFileSystem struct {
	app     pkg.Drive
	Prefix  string
	handler *webdav.Handler
}

func (h *CloudFileSystem) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	useNative := true
	status, err := http.StatusBadRequest, errUnsupportedMethod
	switch r.Method {
	case "PUT":
		useNative = false
		status, err = h.handlePut(w, r)
	case "COPY":
		useNative = false
		status, err = h.handleCopyMove(w, r)

	case "POST":
		reqPath, statusFlag, errFlag := h.stripPrefix(r.URL.Path)
		if errFlag != nil {
			log.Println(statusFlag, errFlag)
			h.handler.ServeHTTP(w, r)
			return
		}
		if reqPath == "/upload" {
			useNative = false
			status, err = h.handlePostUpload(w, r)
			if status == http.StatusCreated {
				w.WriteHeader(status)
				w.Write([]byte("{{\"code\":200, \"msg\":\"OK\"}}"))
			} else {
				w.WriteHeader(status)
				w.Write([]byte("{{\"code\":500, \"msg\":\"" + err.Error() + "\"}}"))
			}
			return
		}
	case "GET":
		// 处理浏览器请求目录，返回文件列表页
		reqPath, statusFlag, errFlag := h.stripPrefix(r.URL.Path)
		if errFlag != nil {
			log.Println(statusFlag, errFlag)
			h.handler.ServeHTTP(w, r)
			return
		}

		// 对特定请求特殊处理
		if reqPath == "/voice_list" {
			useNative = false
			status, err = h.handleVoiceList(w, r)
			return
		} else if strings.HasPrefix(reqPath, "/music_list_item/") {
			folderName := strings.TrimPrefix(reqPath, "/music_list_item/")
			status, err = h.handleMusicListItem(w, r, folderName)
			return
		} else if strings.HasPrefix(reqPath, "/voice_list_item/") {
			folderName := strings.TrimPrefix(reqPath, "/voice_list_item/")
			status, err = h.handleVoiceListItem(w, r, folderName)
			return
		}

		ctx := r.Context()
		f, errFlag := h.OpenFile(ctx, reqPath, os.O_RDONLY, 0)
		if errFlag != nil {
			log.Println(errFlag)
			h.handler.ServeHTTP(w, r)
			return
		}
		defer f.Close()
		fi, errFlag := f.Stat()
		if errFlag != nil {
			log.Println(errFlag)
			h.handler.ServeHTTP(w, r)
			return
		}
		if fi.IsDir() {
			// 增加浏览器返回文件列表页面
			useNative = false
			status, err = h.handleGetDir(w, r, r.URL.Path, f)
			fmt.Println(status, err)
			//return
		}
	}
	if useNative {
		h.handler.ServeHTTP(w, r)
		return
	}
	if err != nil {
		log.Println(err)
	}
	if status != 0 {
		w.WriteHeader(status)
		if status != http.StatusNoContent {
			w.Write([]byte(webdav.StatusText(status)))
		}
	}
}

func (f *CloudFileSystem) Mkdir(ctx context.Context, name string, perm os.FileMode) error {
	if strings.HasSuffix(name, "/") {
		name = strings.TrimSuffix(name, "/")
	}
	return f.app.Mkdir(name)
}
func (f *CloudFileSystem) OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (webdav.File, error) {
	//log.Println("open file", name)
	if flag&os.O_CREATE != 0 {
		return empty, nil
	}
	return newRead(f.app, name)
}
func (f *CloudFileSystem) RemoveAll(ctx context.Context, name string) error {
	return f.app.Delete(name)
}
func (f *CloudFileSystem) Rename(ctx context.Context, oldName, newName string) error {
	return f.app.Move(newName, oldName)
}
func (f *CloudFileSystem) Stat(ctx context.Context, name string) (os.FileInfo, error) {
	return f.app.Stat(name)
}
